<template>
  <div class="vue-fast-table" ref="table" v-bind:class="scrollDirection">
    <!-- 表头 -->
    <div class="table-head">
      <div
        class="module"
        v-bind:style="{ transform: 'translateX(' + scrollLeft + 'px)' }"
        v-for="(item, index) in monthData"
        v-bind:key="index"
      >
        <table cellspacing="0" cellpadding="0">
          <thead>
            <tr>
              <td colspan="30">{{ item.month }}</td>
            </tr>
            <tr>
              <td
                width="100"
                v-for="(d_item, d_index) in item.pointName"
                v-bind:key="d_index"
                style="min-width: 100px"
              >
                {{ d_item }}
              </td>
            </tr>
          </thead>
        </table>
      </div>
    </div>

    <!-- 表体 -->
    <div class="table-body" @scroll="tableScroll" style="height: 300px">
      <div
        class="module"
        v-for="(item, index) in monthData"
        :style="{ width: index === 0 ? '3000px' : 0 }"
        v-bind:key="index"
      >
        <div class="content" v-if="Math.abs(index - curModule) < 3 && index === 0">
          <div
            class="row"
            style="height: 30px"
            v-for="(p_item, p_index) in projectData"
            v-bind:key="p_index"
          >
            <table
              width="3000"
              v-if="Math.abs(p_index - curRow) < 100"
              cellspacing="0"
              cellpadding="0"
            >
              <tbody>
                <tr>
                  <td
                    @click="clickTd(p_index, item.month, d_item, $event)"
                    v-for="(d_item, d_index) in item.days"
                    v-bind:key="d_index"
                  >
                    <!-- {{ getProject(originProjectData[p_index]['' + item.month], item.days) }} -->
                    <span
                      v-if="
                        originProjectData[p_index]['' + item.month]['' + d_item] &&
                        !originProjectData[p_index]['' + item.month]['' + d_item]['show']
                      "
                    >
                      {{ originProjectData[p_index]['' + item.month]['' + d_item]['last'] }}
                    </span>
                    <input
                      @blur="blurTd(p_index, item.month, d_item)"
                      v-if="
                        originProjectData[p_index]['' + item.month]['' + d_item] &&
                        originProjectData[p_index]['' + item.month]['' + d_item]['show']
                      "
                      v-model="originProjectData[p_index]['' + item.month]['' + d_item]['last']"
                      v-focus="originProjectData[p_index]['' + item.month]['' + d_item]['focus']"
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
    <!-- 固定列 -->
    <div class="table-fix-cloumns">
      <!-- 固定列 -->
      <div class="module fix-left-top">
        <table width="100" cellspacing="0" cellpadding="0">
          <thead>
            <tr>
              <td class="fix_divider">
                <span class="lt">毕业要求及指标点</span>
                <span class="lb">课程</span>
              </td>
            </tr>
          </thead>
        </table>
      </div>
      <!-- 固定行 -->
      <div class="module" v-bind:style="{ transform: 'translateY(' + scrollTop + 'px)' }">
        <table width="100" cellspacing="0" cellpadding="0">
          <thead>
            <tr v-for="(item, index) in projectData" v-bind:key="index">
              <td>{{ item.name }}</td>
            </tr>
          </thead>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import JsonData from '../../public/resource/target.json'

export default {
  name: 'vueFastTable',
  components: {},
  data() {
    return {
      scrollLeft: 0,
      scrollTop: 0,
      scrollDirection: '',
      monthArray: [],
      projectArray: [],
      curModule: 0,
      curRow: 0,
      originProjectData: [],
      projectData: [],
      monthData: [],
      options: {
        rowHeight: 30,
        colWidth: 100
      }
    }
  },
  methods: {
    tableScroll(e) {
      const scrollLeft = e.target.scrollLeft
      const scrollTop = e.target.scrollTop
      if (scrollLeft == this.scrollLeft) {
        this.scrollDirection = 'vertical'
      } else {
        this.scrollDirection = 'horizontal'
      }
      this.curModule = parseInt(scrollLeft / 3000)
      this.curRow = parseInt(scrollTop / 30)
      this.scrollLeft = -scrollLeft
      this.scrollTop = -scrollTop
    },
    clickTd(p_index, month, d_index, e) {
      this.originProjectData[p_index]['' + month]['' + d_index]['show'] = true
      this.originProjectData[p_index]['' + month]['' + d_index]['focus'] = true
    },
    blurTd(p_index, month, d_index) {
      this.originProjectData[p_index]['' + month]['' + d_index]['show'] = false
      this.originProjectData[p_index]['' + month]['' + d_index]['focus'] = false
    },

    getProject(v1, v2) {
      console.log('%c [  ]-162', 'font-size:13px; background:pink; color:#bf2c9f;', v1)
      console.log('%c [  ]-163', 'font-size:13px; background:pink; color:#bf2c9f;', v2)
      debugger
    },
    initData(monthNum, projectNum) {
      let originProjectCourseData = []
      let CourseReqData = []

      const courses = JsonData.courses
      const graduationRequirements = JsonData.graduationRequirements

      const projectCoursesData = courses.map(({ course, courseId, points }) => {
        const pointsObject = points.reduce((acc, { pointId, weight }) => {
          acc[pointId] = weight
          return acc
        }, {})
        return { course, name: course, courseId, ...pointsObject }
      })

      // 课程
      for (let index = 0; index < courses.length; index++) {
        const element = courses[index]
        let projectTeam = {}

        graduationRequirements.forEach((d_item, d_index) => {
          let team = {}
          if (index === d_index) {
            CourseReqData.push({
              requestContext: d_item.requestContext,
              requestId: d_item.requestId,
              requestName: d_item.requestName,
              month: d_item.requestName,
              days: courses[index].points.map((c_item) => c_item.pointId),
              pointName: d_item.pointDtos.map((c_item) => c_item.pointName)
            })
          }

          d_item.pointDtos.forEach((p_item) => {
            element.points.forEach((e_item) => {
              if (p_item.pointId === e_item.pointId) {
                team[p_item.pointId] = {
                  last: e_item.weight,
                  max: 1,
                  show: false,
                  focus: false
                }
              }
            })
          })
          projectTeam[d_item.requestName] = team
        })
        originProjectCourseData.push(projectTeam)
      }

      this.monthData = CourseReqData
      this.projectData = projectCoursesData
      this.originProjectData = originProjectCourseData
    }
  },
  mounted() {
    // 开始计时
    const start = performance.now()
    this.initData()
    // 结束计时
    const end = performance.now()
    console.log(`执行时间 ${end - start} 毫秒`)
  }
}
</script>

<style lang="scss" scoped>
.vue-fast-table {
  overflow: hidden;
  position: relative;
  td {
    background: #fff;
    height: 30px;
  }
  &.vertical {
    .table-head {
      z-index: 1;
    }
  }
  input {
    width: 50px;
    height: 16px;
    box-sizing: border-box;
  }
}
.table-head {
  position: relative;
  display: -webkit-box;
  margin-left: 100px;
  .module {
    td {
      width: 10px;
      text-align: center;
      border: 1px solid #ccc;
      box-sizing: border-box;
      text-wrap: nowrap;
    }
  }
}
.table-body {
  display: -webkit-box;
  overflow: auto;
  height: 160px;
  margin-left: 100px;
  .module {
    td {
      display: inline-block;
      width: 100px;
      text-align: center;
      border: 1px solid #ccc;
      box-sizing: border-box;
    }
  }
}
.table-fix-cloumns {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  padding-top: 60px;

  .module {
    td {
      display: inline-block;
      overflow: hidden;
      width: 100px;
      height: 30px;
      text-align: center;
      border: 1px solid #ccc;
      box-sizing: border-box;
      text-wrap: nowrap;
    }
    .fix_divider {
      height: 60px;
    }
  }
  .fix-left-top {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 40px;
    z-index: 1;
  }
}
input {
  // display: none;
}
</style>
